package com.gitee.wsl.reflect.func.value

import com.gitee.wsl.func.expression.visitor.ExpressionVisitor

/**
 * A [Value] that wraps an [Iterable] collection of [Value] elements.
 * @param T type of the elements
 * @see OrderedCollectionValue
 * @see UnorderedCollectionValue
 * @see GeneralCollectionValue
 * @see PairValue
 */
interface IterableValue<T : OutputValue<*>> : InputValue<Iterable<T>>, OutputValue<Iterable<T>>, Destructurable<T>, Iterable<T> {
    override val unwrappedValue: Iterable<T>

    override fun iterator(): Iterator<T> = unwrappedValue.iterator()

    override val destructurableComponents: List<T>
        get() = unwrappedValue.toList()
}

/**
 * An immutable [Value] that contains other values of the same type. The kind of ordering is not relevant.
 * When exporting to a node via [com.quarkdown.core.function.value.output.node.NodeOutputValueVisitor],
 * this collection is simply converted to a group of nodes.
 * @param T the element type of the list
 */
data class GeneralCollectionValue<T : OutputValue<*>>(override val unwrappedValue: Iterable<T>) : IterableValue<T> {
    override fun <T> accept(visitor: ExpressionVisitor<T>): T = visitor.visit(this)
}

fun <T : OutputValue<*>> Value.Companion.of(unwrappedValue: Iterable<T>) = GeneralCollectionValue(unwrappedValue)